package com.example.shirotest.study;

import java.util.Scanner;

public class HashTabTest {

    public static void main(String[] args) {
        HashTable hashTable = new HashTable(7);

        //写一个简单的菜单
        String key = "";
        Scanner scanner = new Scanner(System.in);

        while (true){
            System.out.println("add: append new emp");
            System.out.println("list: show all emp");
            System.out.println("find: find emp by id");
            System.out.println("exit: exit system");

            key = scanner.next();
            switch (key){
                case "add":
                    System.out.println("input id:");
                    int id = scanner.nextInt();
                    System.out.println("input name:");
                    String name = scanner.next();
                    //创建雇员
                    Emp emp = new Emp(id,name);
                    hashTable.add(emp);
                    break;
                case "list":
                    hashTable.list();
                    break;
                case "find":
                    System.out.println("input id you search:");
                    id = scanner.nextInt();
                    hashTable.findEmpById(id);
                    break;
                case "exit":
                    scanner.close();
                    System.exit(0);
                    break;
                default:
                    break;
            }
        }


    }

}

//雇员类
class Emp{
    public int id;
    public String name;
    public Emp next;
    public Emp(int id,String name){
        this.id = id;
        this.name = name;
    }
}

//链表管理器，用于对当前链表中的数据（Emp）进行增删改查
class EmpLinkedList{
    //头指针，指向第一个Emp
    private Emp head;

    //添加雇员到链表
    //假定，当添加雇员时，id是自增长，即id的分配总是从小到大
    //因此我们将该雇员直接加入到本链表的最后即可
    public void add(Emp emp){
        if(head == null){
            head = emp;
            return;
        }

        Emp curEmp = head;
        while (true){
            if(curEmp.next == null){
                curEmp.next = emp;
                break;
            }

            curEmp = curEmp.next;
        }
    }

    //遍历链表的雇员信息
    public void list(int i){
        if(head == null){
            System.out.printf("LinkedList No: %d is empty\n",(i+1));
            return;
        }

        System.out.printf("LinkedList No: %d : ",(i+1));
        Emp curEmp = head;
        while (true){
            System.out.printf("=> id=%d name=%s\t",curEmp.id,curEmp.name);
            if(curEmp.next == null){
                break;
            }
            curEmp = curEmp.next;
        }
        System.out.println();
    }

    //根据id查找雇员
    public Emp findEmpById(int id){
        if(head == null){
            System.out.println("The LinkedList is empty");
            return null;
        }

        Emp curEmp = head;
        while (true){
            if(curEmp.id == id){  //找到
                break;
            }

            if(curEmp.next == null){ //未找到
                curEmp = null;
                break;
            }
            curEmp = curEmp.next;
        }

        return curEmp;
    }

}

//管理多条链表
class HashTable{
   private EmpLinkedList[] empLinkedListArray;
   private int size;

   //构造器
    public HashTable(int size){
        this.size = size;
        empLinkedListArray = new EmpLinkedList[size];
        //分别初始化每一个链表
        for (int i = 0; i <size; i++) {
            empLinkedListArray[i] = new EmpLinkedList();
        }
    }

    //添加雇员
    public void add(Emp emp){
        int empLinkedListNo = hashFun(emp.id);
        empLinkedListArray[empLinkedListNo].add(emp);
    }

    //遍历所有的链表
    public void list(){
        for (int i = 0; i < size; i++) {
            empLinkedListArray[i].list(i);
        }
    }

    //根据id，查找雇员
    public void findEmpById(int id){
        int empLinkedListNo = hashFun(id);
        Emp emp = empLinkedListArray[empLinkedListNo].findEmpById(id);
        if(emp == null){
            System.out.println("Find nothing in the LinkedList");
        }else {
            System.out.printf("LinkedList No: %d find the Emp id=%d\n",(empLinkedListNo+1),id);
        }

    }

    //编写散列（hash）函数,一个简单取模算法
    private int hashFun(int id){
        return id % size;
    }

}
